package com.wfh.frp.server;

import com.wfh.frp.coder.ProxMsgEncoder;
import com.wfh.frp.coder.ProxyMsgDecoder;
import com.wfh.frp.handler.VisitorHandler;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.DefaultChannelProgressivePromise;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import lombok.extern.slf4j.Slf4j;

/**
 * @Title: VisitorServer
 * @Author wangfenghuan
 * @Package com.wfh.frp.server
 * @Date 2025/10/8 10:12
 * @description: 访客服务
 */
@Slf4j
public class VisitorServer {

    /**
     * 主线程处理连接
     */
    private static final EventLoopGroup boss = new NioEventLoopGroup(1);

    /**
     * 工作线程处理io
     */
    private static final EventLoopGroup word = new NioEventLoopGroup();

    /**
     * 启动服务
     * @param port
     * @param serverHost
     * @param serverPort
     */
    public static void start(int port, String serverHost, int serverPort){
        while (true) {
            try {
                ServerBootstrap serverBootstrap = new ServerBootstrap();
                serverBootstrap.group(boss, word);
                serverBootstrap.channel(NioServerSocketChannel.class);
                serverBootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel socketChannel) throws Exception {
                        socketChannel.pipeline()
                                 .addLast(new ProxMsgEncoder())
                                 .addLast(new ProxyMsgDecoder())
                                // .addLast( new HttpObjectAggregator(65535))
                                .addLast(new VisitorHandler(serverHost, serverPort));
                    }
                });

                ChannelFuture bindFuture = serverBootstrap.bind(port);
                bindFuture.awaitUninterruptibly();

                if (bindFuture.isSuccess()) {
                    log.info("Visitor server started on port: {}", port);
                    bindFuture.channel().closeFuture().sync();
                    log.info("Server stopped, attempting to restart...");
                } else {
                    log.warn("Failed to start visitor server on port: {}, retrying in 3 seconds...", port);
                    Thread.sleep(3000);
                }
            } catch (Exception e) {
                log.error("Server error: {}", e.getMessage());
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException ie) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
        }
        boss.shutdownGracefully();
        word.shutdownGracefully();
    }

}
